<template>
  <div class="dy-calendar">
    <div class="dy-head">
      <span class="dy-date">{{curYear+"年"+curMonth+"月"}}</span>
      <div class="dy-btn">
        <van-icon name="arrow-left" size="20" @click="onPreMonth" />
        <van-icon name="arrow" style="margin:0 30px" size="20" @click="onNextMonth" />
      </div>
    </div>

    <div class="dy-body">
      <div class="dy-title">
        <div class="dy-cell" v-for="(item,index) in titleList" :key="index">{{item}}</div>
      </div>
      <div class="dy-day">
        <div
          class="dy-cell"
          :class="{pointer:item!==0}"
          v-for="(item,index) in dayList"
          :key="index"
          @click="onClickDay(item)"
        >
          <span
            v-if="item!==0"
            class="dy-text"
            :class="{today:item.isToday,select:item.day==selectDay, 'has-course':hasCourse(item.date)}"
          >{{item.day}}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "",
  data() {
    return {
      event: {
        onCurDate: "onCurDate",
        onChangeDate: "onChangeDate",
        onClickDay: "onClickDay"
      },
      curYear: 2019,
      curMonth: 8,
      titleList: ["一", "二", "三", "四", "五", "六", "日"],
      dayList: [],
      dayOfMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
      nowDate: new Date(),
      selectDay: 0
    };
  },
  props: {
    courseDate: {
      type: Array,
      default() {
        return [];
      }
    },
    firstDay: {
      type: Number,
      default: 1,
      validator(val) {
        if (val >= 1 && val <= 7) {
          return true;
        }
        return false;
      }
    }
  },
  components: {},
  mounted() {
    const tmpAry = this.titleList.splice(0, this.firstDay - 1);
    this.titleList = this.titleList.concat(tmpAry);

    this.init(this.nowDate);

    this.selectDay = this.nowDate.getDate();
  },
  computed: {
    courseDateSet() {
      const retAry = [];
      this.courseDate.forEach(v => {
        retAry.push(new Date(v.replace(/-/g, "/")));
      });
      return retAry;
    }
  },
  methods: {
    onPreMonth() {
      this.curYear = this.curMonth - 1 <= 0 ? this.curYear - 1 : this.curYear;
      this.curMonth = this.curMonth - 1 <= 0 ? 12 : this.curMonth - 1;
      this.selectDay = 0;
      this.init(new Date(`${this.curYear}/${this.curMonth}/1`));
      this.$emit(this.event.onChangeDate, `${this.curYear}-${this.curMonth}-1`);
    },
    onNextMonth() {
      this.curYear = this.curMonth + 1 > 12 ? this.curYear + 1 : this.curYear;
      this.curMonth = this.curMonth + 1 > 12 ? 1 : this.curMonth + 1;
      this.selectDay = 0;
      this.init(new Date(`${this.curYear}/${this.curMonth}/1`));
      this.$emit(this.event.onChangeDate, `${this.curYear}-${this.curMonth}-1`);
    },
    onClickDay(item) {
      this.selectDay = item.day;
      this.$emit(
        this.event.onClickDay,
        `${this.curYear}-${this.curMonth}-${item.day}`
      );
    },
    // other
    init(date) {
      // current
      this.curYear = date.getFullYear();
      this.curMonth = date.getMonth() + 1;
      // day of month
      if (this.isLeapYear(date.getFullYear())) {
        this.dayOfMonth[1] = 29;
      }
      // day list
      const year = date.getFullYear(),
        month = date.getMonth();
      const dayList = [];
      this.dayList = [];
      const dayCount = this.dayOfMonth[month];
      let firstDayWeek = new Date(year, month, 1).getDay();
      firstDayWeek = firstDayWeek == 0 ? 7 : firstDayWeek;
      firstDayWeek = (firstDayWeek - this.firstDay + 7) % 7;
      for (let i = 1; i <= firstDayWeek; ++i) {
        dayList.push(0);
      }
      for (let i = 1; i <= dayCount; ++i) {
        dayList.push(i);
      }
      for (const i of dayList) {
        if (i == 0) {
          this.dayList.push(i);
        } else {
          const date = new Date(year, month, i);
          this.dayList.push({
            date,
            day: i,
            isToday: this.isDateEqual(date, this.nowDate)
          });
        }
      }
    },
    isLeapYear(year) {
      if (year % 100 == 0) {
        return year % 400 == 0;
      }
      return year % 4 == 0;
    },
    isDateEqual(date1, date2) {
      if (
        date1.getFullYear() == date2.getFullYear() &&
        date1.getMonth() == date2.getMonth() &&
        date1.getDate() == date2.getDate()
      ) {
        return true;
      }
      return false;
    },
    hasCourse(date) {
      for (const i of this.courseDateSet) {
        if (this.isDateEqual(i, date)) {
          return true;
        }
      }
      return false;
    }
  }
};
</script>

<style scoped>
.dy-calendar{
    background: #fff;
    padding: 40px 0 30px 0;
}
.dy-calendar>.dy-head{
    font-size: 22px;
    color: #595959;
    text-align: left;
    margin-bottom: 30px;
}
.dy-calendar>.dy-head>.dy-date{
    margin: 0 49px;
}
.dy-calendar>.dy-head>.dy-btn{
    float: right;
}
.dy-calendar>.dy-body .dy-cell{
    width: 14%;
    height: 60px;
    display: block;
    float: left;
    text-align: center;
    position: relative;
}
.dy-calendar>.dy-body .pointer{
    cursor: pointer;
}
.dy-calendar>.dy-body>.dy-title{
    font-size: 14px;
    color: #8c8c8c;
}
.dy-calendar>.dy-body>.dy-title::after{
    content: "";
    display: block;
    clear: both;
}
.dy-calendar>.dy-body>.dy-day{
    font-size: 15px;
    font-weight: 800;
    color: #595959;
    position: relative;
}
.dy-calendar>.dy-body>.dy-day .today{
    color: #eb6100;
    background: rgba(235, 97, 0, 0.1);
    width: 34px;
    height: 34px;
    border-radius: 50%;
}
.dy-calendar>.dy-body>.dy-day .has-course{
    position: relative;
}
.dy-calendar>.dy-body>.dy-day .has-course::after{
    content: "";
    display: block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    position: absolute;
    left: 50%;
    bottom: -15px;
    transform: translateX(-50%);
    background: #eb6100;
}
.dy-calendar>.dy-body>.dy-day .dy-text{
    display: inline-block;
    line-height: 34px;
}
.dy-calendar>.dy-body>.dy-day .select{
   color: #fff;
   background: #eb6100;
   width: 34px;
   height: 34px;
   border-radius: 50%;
}
.dy-calendar>.dy-body>.dy-day .select::after{
    content: "";
    display: block;
    clear: both;
}
</style>